﻿using System;
using System.IO;
using System.Windows.Forms;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;

namespace SelfCert
{
	public partial class FrmIssuerCert : Form
	{
		private X509Certificate m_issuerCert = null;

		public X509Certificate IssuerCert { get { return m_issuerCert; } }

		private AsymmetricCipherKeyPair m_issuerKeyPair = null;

		public AsymmetricCipherKeyPair IssuerKeyPair { get { return m_issuerKeyPair; } }

		public FrmIssuerCert()
		{
			InitializeComponent();
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.Close();
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			var pwd = txtPassword.Text.Trim();

			var pfxFile = txtFile.Text;

			var pubFile = pfxFile.Substring(0, pfxFile.Length - 4) + ".public";
			var priFile = pfxFile.Substring(0, pfxFile.Length - 4) + ".private";
			try
			{
				using (var fs = new FileStream(pfxFile, FileMode.Open, FileAccess.Read, FileShare.Read))
				{
					//if (pwd.IsNullOrWhiteSpace())
					//{
					//	var parser = new X509CertificateParser();
					//	m_issuerCert = parser.ReadCertificate(fs);
					//}
					//else
					//{
					var store = new Pkcs12StoreBuilder().Build();
					store.Load(fs, pwd.ToCharArray());

					string pName = null;
					foreach (string n in store.Aliases)
					{
						if (store.IsKeyEntry(n))
						{
							pName = n;
							//break;
						}
					}
					var ch = store.GetCertificateChain(pName);
					m_issuerCert = ch[0].Certificate;
					//}
				}
			}
			catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }

			RsaKeyParameters rsaPublic = null;
			BigInteger rsaPubMod = null;
			BigInteger rsaPubExp = null;

			#region 公钥

			try
			{
				using (var sr = new StreamReader(pubFile))
				{
					var line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace())
					{
						rsaPubMod = new BigInteger(Convert.FromBase64String(line));
					}
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace())
					{
						rsaPubExp = new BigInteger(Convert.FromBase64String(line));
					}
					if (rsaPubMod != null && rsaPubExp != null)
					{
						rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp);
					}
				}
			}
			catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }

			#endregion

			RsaPrivateCrtKeyParameters rasPrivateParameters = null;

			#region 私钥

			try
			{
				using (var sr = new StreamReader(priFile))
				{
					BigInteger rsaPrivMod = null;
					BigInteger rsaPrivDP = null;
					BigInteger rsaPrivDQ = null;
					BigInteger rsaPrivExp = null;
					BigInteger rsaPrivP = null;
					BigInteger rsaPrivQ = null;
					BigInteger rsaPrivQinv = null;
					var line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivMod = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivDP = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivDQ = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivExp = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivP = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivQ = new BigInteger(Convert.FromBase64String(line)); }
					line = sr.ReadLine();
					if (!line.IsNullOrWhiteSpace()) { rsaPrivQinv = new BigInteger(Convert.FromBase64String(line)); }
					if (rsaPubExp != null && rsaPrivMod != null && rsaPrivDP != null && rsaPrivDQ != null && rsaPrivExp != null && rsaPrivP != null && rsaPrivQ != null && rsaPrivQinv != null)
					{
						rasPrivateParameters = new RsaPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv);
					}
				}
			}
			catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }

			#endregion

			if (rsaPublic != null && rasPrivateParameters != null)
			{
				m_issuerKeyPair = new AsymmetricCipherKeyPair(rsaPublic, rasPrivateParameters);
			}
			this.DialogResult = System.Windows.Forms.DialogResult.OK;
			this.Close();
		}

		private void cmdBrowse_Click(object sender, EventArgs e)
		{
			var fileDialog = new OpenFileDialog();
			fileDialog.Filter = "PFX file (*.pfx)|*.pfx";

			if (DialogResult.OK == fileDialog.ShowDialog(this))
			{
				txtFile.Text = fileDialog.FileName;
			}
		}
	}
}
